#pragma Once
#include <iostream>
#include <queue>
#include <pthread.h>
#include <unistd.h>
template <class T>
class Blockqueue
{
    private:
        bool FULL(void)
        {
            return _q.size()==_cap;
        }
        bool Empty(void)
        {
            return _q.empty();
        }
    public:
        Blockqueue()
        {
            pthread_cond_init(&full,nullptr);
            pthread_cond_init(&emp,nullptr);
            pthread_mutex_init(&lock,nullptr);
        }
        ~Blockqueue()
        {
            pthread_cond_destroy(&full);
            pthread_cond_destroy(&emp);
            pthread_mutex_destroy(&lock);
        }
        //对阻塞队列操作需要加锁，保证互斥
        void push(const T& val)
        {
            pthread_mutex_lock(&lock);
            if(FULL())
            {
                //进入等待队列，生产者与消费者也是有同步关系的
                pthread_cond_wait(&full,&lock); 
            }
            _q.push(val);
            pthread_mutex_unlock(&lock);
            pthread_cond_signal(&emp);//生产完了，可以继续消费了
            sleep(3);
        }
        void pop(T& data)
        {
            pthread_mutex_lock(&lock);
            if(Empty())
            {

                //进入等待队列，生产者与消费者也是有同步关系的
            }
            data=_q.front();
            _q.pop();
            pthread_mutex_unlock(&lock);
            pthread_cond_signal(&full);
            sleep(1);
        }
    private:
        std::queue<T> _q;
        int _cap=5;//阻塞队列中的最大容量
        pthread_mutex_t lock;//_q作为临界资源，对临界资源加锁对其进行保护
        pthread_cond_t full;
        pthread_cond_t emp;
};
